home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvdesk.cpp < prev    next >
C/C++ Source or Header  |  1998-01-05  |  12KB  |  542 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVDESK.CPP                           |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Desktop support implementation       |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_app
  16. #define uses_colors
  17. #define uses_config
  18. #define uses_ini
  19. #define uses_desk
  20. #define uses_dialog
  21. #define uses_help
  22. #define uses_icons
  23. #define uses_lbox
  24. #define uses_cmdgen
  25.  
  26. #define DECLARE_PVDESK
  27. #include "PVuses.h"
  28. #undef DECLARE_PVDESK
  29.  
  30. void insert_window( Titem *item, int x, int y )
  31. {
  32.   if( is_valid( item ) ) desktop->put_in( item, x, y );
  33. }
  34.  
  35. Tdesktop::Tdesktop( void ):
  36.   Titem( 1, 1 )
  37. {
  38.   backgrnd_attr = pal_desktop.normal;
  39.   max_tileable = 64;
  40.   tile_columns = 1;
  41.   iconize_x = 2;
  42.   iconize_y = yl - 2;
  43.   tile_rect_x = 0;
  44.   tile_rect_y = 0;
  45.   tile_rect_xl = xl;
  46.   tile_rect_yl = yl;
  47. }
  48.  
  49. void Tdesktop::resize( int _xl, int _yl )
  50. {
  51.   iconize_x = 2;
  52.   iconize_y = _yl - 2;
  53.   tile_rect_x = 0;
  54.   tile_rect_y = 0;
  55.   tile_rect_xl = _xl;
  56.   tile_rect_yl = _yl;
  57.   Titem::resize( _xl, _yl );
  58. }
  59.  
  60. void Tdesktop::put_in( Titem *v, int _x, int _y )
  61. {
  62.   Titem::put_in( v, _x, _y ) ;
  63.   update_commands();
  64. }
  65.  
  66. boolean Tdesktop::remove( Titem *v )
  67. {
  68.   if( !Titem::remove( v ) ) return 0;
  69.   update_commands();
  70.   return 1;
  71. }
  72.  
  73. void Tdesktop::update_commands( void )
  74. {
  75.   Titem *p;
  76.   uint f, c, s, t, i;
  77.  
  78.   c = s = t = i = 0;
  79.   p = first();
  80.   while( p != NULL )
  81.   {
  82.     f = p->flags_word;
  83.     if( p->state( isALIVE ) )
  84.     {
  85.       if( f & ifCLOSEABLE  ) c++;
  86.       if( f & ifSELECTABLE ) s++;
  87.       if( f & ifTILEABLE ) t++;
  88.       if( p->state( isICONIZED ) ) i++;
  89.     }
  90.     p = p->nextl();
  91.   }
  92.   if( !s ) set_context( -1 );
  93.   cstate( cmWINDOW_TILE, t != 0 );
  94.   cstate( cmWINDOW_CASCADE, t != 0 );
  95.   cstate( cmWINDOW_ARRANGE_ICONS, i != 0 );
  96.   cstate( cmWINDOW_CLOSE_ALL, c && s != 0);
  97.   cstate( cmWINDOW_NEXT, s > 1 );
  98.   cstate( cmWINDOW_PREVIOUS, s > 1 );
  99. }
  100.  
  101. void Tdesktop::tab_next( int direction )
  102. {
  103.   Titem *p, *l, *ll;
  104.  
  105.   if( current == NULL ) return;
  106.   if( direction > 0 )
  107.   {
  108.     p = ll = current;
  109.     l = last;
  110.     do
  111.     {
  112.       ll = ll->next;
  113.       if( ll->flags( ifSELECTABLE ) && ll->state( isALIVE ) )
  114.       {
  115.         l = p;
  116.         p = ll;
  117.       }
  118.     }
  119.     while( ll != last );
  120.   }
  121.   else
  122.   {
  123.     p = current;
  124.     do
  125.     {
  126.       l = p;
  127.       p = p->next;
  128.     }
  129.     while( ( !p->flags( ifSELECTABLE ) || !p->state( isALIVE ) ) &&
  130.            ( p != current ) );
  131.   }
  132.   if( p != current )
  133.   {
  134.     last = l;
  135.     items_changed = 1;
  136.     pop_top_items();
  137.     p->focus();
  138.   }
  139. }
  140.  
  141. void Tdesktop::close_all( void )
  142. {
  143.   Titem *p;
  144.   int n, i, cancel;
  145.  
  146.   p = first();
  147.   n = 1;
  148.   while( p != NULL )
  149.   {
  150.     if( p->flags( ifCLOSEABLE ) &&
  151.         p->state( isALIVE ) &&
  152.         p->flags( ifSELECTABLE ) ) n++;
  153.     p = p->nextl();
  154.   }
  155.   cancel = 1;
  156.   while( --n )
  157.   {
  158.     p = first();
  159.     i = cancel;
  160.     while( !p->flags( ifCLOSEABLE ) ||
  161.            !p->state( isALIVE ) ||
  162.            !p->flags( ifSELECTABLE ) ||
  163.            --i ) p = p->nextl();
  164.     if( ( message( p, cmDONE ) != p ) && p->state( isALIVE ) ) cancel++;
  165.   }
  166. }
  167.  
  168. static uint square_root( uint x )
  169. {
  170.   uint i, j;
  171.   for( i = 1, j = 0; j <= x; i += 2 )
  172.     j += i;
  173.   return ( i - 1 ) / 2 - 1;
  174. }
  175.  
  176. /*
  177.   Description:
  178.     Try to tile subitems. If tile fails, undo tile and call tile_error().
  179. */
  180. #define dv( n, a )  (( a ) - ( n )+( ( n ) / ( a ) ) * ( a ))
  181. static int r, cl, dx, dy, xx, yy, al, bl, mx, my;
  182.  
  183. void Tdesktop::tile( void )
  184. {
  185.   Titem *p;
  186.   int n, c;
  187.  
  188.   if( last == NULL ) return;
  189.   iconize_x = 2;
  190.   iconize_y = yl - 2;
  191.   tile_rect_x = 0;
  192.   tile_rect_y = 0;
  193.   tile_rect_xl = xl;
  194.   tile_rect_yl = yl;
  195.   message( this, cmARRANGING );
  196.   n = 0;
  197.   p = first();
  198.   while( p != NULL )
  199.   {
  200.     if( !p->state( isICONIZED ) )
  201.       if( p->flags( ifTILEABLE ) && p->state( isALIVE ) )
  202.         n++;
  203.       else
  204.         message( p, cmARRANGING );
  205.     p = p->nextl();
  206.   }
  207.   if( !n ) return;
  208.   if( n > max_tileable )
  209.   {
  210.     if( tile_error != NULL ) tile_error();
  211.   }
  212.   else
  213.   {
  214.     c = square_root( n );
  215.     r = n / c;
  216.     cl = c - n + c * r;
  217.     if( tile_columns )
  218.     {
  219.       mx = tile_rect_yl;
  220.       my = tile_rect_xl;
  221.     }
  222.     else
  223.     {
  224.       mx = tile_rect_xl;
  225.       my = tile_rect_yl;
  226.     }
  227.     al = mx / c; bl = my / r;
  228.     p = last;
  229.     dx = dv( mx, c ); dy = dv( my, r );
  230.     xx = 0; yy = 0;
  231.     do_tile( last );
  232.     redraw();
  233.   }
  234. }
  235.  
  236. /*
  237.   Description:
  238.     Try to cascade subitems. If cascade fails, undo cascade and call
  239.     tile_error().
  240. */
  241. static char undo;
  242.  
  243. void Tdesktop::cascade( void )
  244. {
  245.   Titem *p;
  246.  
  247.   if( last == NULL ) return;
  248.   iconize_x = 2;
  249.   iconize_y = yl - 2;
  250.   tile_rect_x = 0;
  251.   tile_rect_y = 0;
  252.   tile_rect_xl = xl;
  253.   tile_rect_yl = yl;
  254.   message( this, cmARRANGING );
  255.   p = first();
  256.   while( p != NULL )
  257.   {
  258.     if( !p->state( isICONIZED ) && !p->flags( ifTILEABLE ) ) message( p, cmARRANGING );
  259.     p = p->nextl();
  260.   }
  261.   undo = 0; xx = tile_rect_x; yy = tile_rect_y;
  262.   do_cascade( last, 1, 1 );
  263.   if( ( undo ) && ( tile_error ) ) tile_error();
  264.   redraw();
  265. }
  266.  
  267. /*
  268.   Description:
  269.     Arranges all iconized subitems.
  270.   Exit:
  271.     1 if at least one icon has been arranged,
  272.     0 otherwise.
  273. */
  274. boolean Tdesktop::arrange_icons( void )
  275. {
  276.   Titem *p;
  277.   char result;
  278.  
  279.   iconize_y = yl - 2;
  280.   iconize_x = 2;
  281.   result = 0;
  282.   p = first();
  283.   while( p != NULL )
  284.   {
  285.     if( p->state( isICONIZED ) )
  286.     {
  287.       arrange_one_icon( p );
  288.       result = 1;
  289.     }
  290.     p = p->nextl();
  291.   }
  292.   return result;
  293. }
  294.  
  295. /*
  296.   Description:
  297.     Arrange one iconized subitem. Usually called when item is iconized for
  298.     the first time.
  299. */
  300. void Tdesktop::arrange_one_icon( Titem *p )
  301. {
  302.   if( p->state( isICONIZED ) )
  303.   {
  304.     if( iconize_x <= xl - p->xl )
  305.       p->drag( iconize_x, iconize_y );
  306.     else
  307.     {
  308.       if( iconize_y>1 ) iconize_y--; else iconize_y = yl - 2;
  309.       iconize_x = 2;
  310.       p->drag( iconize_x, iconize_y );
  311.     }
  312.     iconize_x += p->xl + 1;
  313.   }
  314. }
  315.  
  316. //Tdesktop protected:
  317.  
  318. #pragma off( unreferenced )
  319. void Tdesktop::calc_bounds( int delta_xl, int delta_yl )
  320. {
  321.   drag( desktop_x, desktop_y );
  322.   resize( desktop_xl, desktop_yl );
  323. }
  324. #pragma on( unreferenced )
  325.  
  326. void Tdesktop::event_handler( Tevent &ev )
  327. {
  328.   backgrnd_char = i_desktop;
  329.   Titem::event_handler( ev );
  330.   switch( ev.code )
  331.   {
  332.     case evCOMMAND:
  333.       switch( ev.CMD_CODE )
  334.       {
  335.         case cmARRANGING:
  336.           tile_rect_x = 0;  tile_rect_y = 0;
  337.           tile_rect_xl = xl; tile_rect_yl = yl;
  338.           if( arrange_icons() )
  339.           {
  340.             tile_rect_yl = yl-5;
  341.             if( tile_rect_yl < iconize_y ) tile_rect_yl = iconize_y-1;
  342.           }
  343.           break;
  344.         case cmWINDOW_NEXT:
  345.           tab_next(  1 ); break;
  346.         case cmWINDOW_PREVIOUS:
  347.           tab_next( -1 ); break;
  348.         case cmWINDOW_TILE:
  349.           tile(); break;
  350.         case cmWINDOW_CASCADE:
  351.           cascade(); break;
  352.         case cmWINDOW_ARRANGE_ICONS:
  353.           arrange_icons(); break;
  354.         case cmWINDOW_CLOSE_ALL:
  355.           close_all(); break;
  356.         case cmWINDOW_LIST:
  357.           list_all(); break;
  358. #ifndef NOHELP
  359.         case cmHELP_CONTENTS:
  360.           online_help( htHELP_CONTENTS ); break;
  361.         case cmHELP_USING:
  362.           online_help( htHELP_ON_HELP ); break;
  363. #endif
  364.         default: goto hot;
  365.       }
  366.       handled( ev );
  367.     hot:
  368.       break;
  369. #ifndef NOMOUSE
  370.     case evMOUSE_DOWN:
  371.       if( ev.INSIDE && ev.CLICKS )
  372.       {
  373.         list_all();
  374.         handled( ev );
  375.       }
  376. #endif
  377.   }
  378. }
  379.  
  380. //Tdeskt